//职责链模式时使多个对象都有机会处理请求，从而避免请求的发送者和接收者之间的耦合关系。
//在职责链模式里，很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个
//链上传递，直到链上的某一个对象决定处理此请求。

interface IHandler {
  addMiddleware(h: IHandler): IHandler;
  get(url: string, callback: (data: any) => void): void;
}

abstract class AbstractHandler implements IHandler {
  next!: IHandler;
  addMiddleware(h: IHandler) {
    this.next = h;
    return this.next;
  }

  get(url: string, callback: (data: any) => void) {
    if (this.next) {
      return this.next.get(url, callback);
    }
  }
}

//定义Auth中间件
class Auth extends AbstractHandler {
  isAuthenticated: boolean;
  constructor(username: string, password: string) {
    super();
    this.isAuthenticated = false;
    if (username === "abao" && password === "123") {
      this.isAuthenticated = true;
    }
  }
  get(url: string, callback: (data: any) => void) {
    if (this.isAuthenticated) {
      return super.get(url, callback);
    } else {
      throw new Error("Not Authorized");
    }
  }
}

//定义Logger中间件
class Logger extends AbstractHandler {
  get(url: string, callback: (data: any) => void) {
    console.log("/GET Request to:", url);
    return super.get(url, callback);
  }
}

class Route extends AbstractHandler {
  URLMaps: { [key: string]: any };
  constructor() {
    super();
    this.URLMaps = {
      "/api/todos": [{ title: "learn ts" }, { title: "learn react" }],
      "/api/random": Math.random(),
    };
  }

  get(url: string, callback: (data: any) => void) {
    super.get(url, callback);

    if (this.URLMaps.hasOwnProperty(url)) {
      {
        callback(this.URLMaps[url]);
      }
    }
  }
}

const route = new Route();
route.addMiddleware(new Auth("abao", "123")).addMiddleware(new Logger());

route.get("/api/todos", (data) => {
  console.log(JSON.stringify({ data }, null, 2));
});

route.get('/api/random',data=>{
    console.log(data);
})

//应用场景
//1.可处理一个请求的对象集合应被动态指定
//2.想在不明确指定接收者的情况下，向多个对象中的一个提交一个请求
//3.有多个对象可以处理一个请求，哪个对象处理该请求运行自动确定，客户端只需要把请求提交到链上即可